package cn.lg.soar.mvc.aspect.idempotent;

import cn.lg.soar.common.data.Soar64;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.exceptions.BaseBException;
import cn.lg.soar.common.util.IpUtil;
import cn.lg.soar.common.util.data.RandomUtil;
import cn.lg.soar.core.config.cache.template.ICacheTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.MessageFormat;
import java.time.Duration;
import java.util.UUID;

/**
 * @author luguoxiang
 * @date 2021/8/25
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class IdempotentService {

    @Autowired
    private ICacheTemplate<String, Object> cacheTemplate;

    private static final String KEY = "md:";
    private static final String IPKEY = "md:{0}:{1}";

    public String getToken() {
        String token = UUID.randomUUID().toString();
        this.setCacheTemplate(IdempotentService.KEY + token);
        return token;
    }

    public boolean checkToken(String token) {
        if (token == null) {
            return false;
        }
        return Boolean.TRUE.equals(this.cacheTemplate.delete(IdempotentService.KEY + token));
    }

    public String getTokenByIp(int ip) {
        int x = (int) System.currentTimeMillis() & 0xFFFFFFFF;
        x = (x << 10) | RandomUtil.getInt(1024);
        String token = Soar64.ofInt(x);
        this.setCacheTemplate(MessageFormat.format(IdempotentService.IPKEY, Soar64.ofInt(ip), token));
        return token;
    }

    public String getTokenByIp(String ip) {
        return getTokenByIp(IpUtil.ip4vToInt(ip));
    }

    public boolean checkTokenByIp(int ip, String token) {
        if (token == null) {
            return false;
        }
        String key = MessageFormat.format(IdempotentService.IPKEY, Soar64.ofInt(ip), token);
        return Boolean.TRUE.equals(
                this.cacheTemplate.delete(key)
        );
    }

    public boolean checkTokenByIp(String ip, String token) {
        return checkTokenByIp(IpUtil.ip4vToInt(ip), token);
    }

    private void setCacheTemplate(String key){
        boolean b = this.cacheTemplate.putIfAbsent(key, 1, Duration.ofHours(1));
        if(b) {
            return;
        }
        throw new BaseBException(0, I18n.build("获取token失败"));
    }
}
